#include "ZeroMQPublisher.h"
#include "ZeroMQRequester.h"
#include "ZeroMQResponder.h"
#include "ZeroMQSubscriber.h"

#define GLOG_USE_GLOG_EXPORT
#include <glog/logging.h>
#include <thread>

using namespace std;

void runPublisher(int port)
{
    char address[128] = {0};
    snprintf(address, 128, "tcp://*:%d", port);

    ZeroMQPublisher pub;
    if (!pub.initialize(address)) {
        return;
    }

    int i = 0;
    while (true) {
        std::string message = "hello, world!" + to_string(i++);
        if (pub.send(message.c_str(), message.length()) <= 0) {
            LOG(INFO) << "send error";
        }
        this_thread::sleep_for(chrono::milliseconds(100));
    }
}

void runSubscriber(const char *ip, int port)
{
    char address[128] = {0};
    snprintf(address, 128, "tcp://%s:%d", ip, port);

    ZeroMQSubscriber sub;
    if (!sub.initialize(address)) {
        LOG(WARNING) << "initialize failed";
        return;
    }

    while (true) {
        char buf[1024] = {0};
        if (sub.recv(buf, 1024) > 0) {
            LOG(INFO) << "recv message: " << buf;
        }
    }
}

void runResponder(int port)
{
    char address[128] = {0};
    snprintf(address, 128, "tcp://*:%d", port);

    ZeroMQResponder rep;
    if (!rep.initialize(address)) {
        LOG(WARNING) << "initialize failed";
        return;
    }

    int i = 0;
    while (true) {
        char buf[1024] = {0};
        if (rep.recv(buf, 1024) > 0) {
            LOG(INFO) << "recv from requester: " << buf;
        }

        std::string message = "hello, requester - " + to_string(i++);
        if (rep.send(message.c_str(), message.length()) <= 0) {
            LOG(INFO) << "send error!";
        }
    }
}

void runRequester(const char *ip, int port)
{
    char address[128] = {0};
    snprintf(address, 128, "tcp://%s:%d", ip, port);

    ZeroMQRequester req;
    if (!req.initialize(address)) {
        LOG(WARNING) << "initialize failed";
        return;
    }

    int i = 0;
    while (true) {
        std::string message = "hello, responder - " + to_string(i++);
        if (req.send(message.c_str(), message.length()) <= 0) {
            LOG(INFO) << "send error!";
        }

        char buf[1024] = {0};
        if (req.recv(buf, 1024) > 0) {
            LOG(INFO) << "recv from responder: " << buf;
        }
        this_thread::sleep_for(chrono::milliseconds(100));
    }
}

void printUsage(const char *cmd)
{
    printf("Usgae: %s <command>\n\n", cmd);
    printf("commands: \n");
    printf(" pub      [port]\n");
    printf(" sub [ip] [port]\n");
    printf(" rsp      [port]\n");
    printf(" req [ip] [port]\n");
}

int main(int argc, char *argv[])
{
#if 1
    if (argc <= 2) {
        printUsage(argv[0]);
    }

    if (strcmp(argv[1], "pub") == 0) {
        if (argc != 3)
            printUsage(argv[0]);

        runPublisher(atoi(argv[2]));
    } else if (strcmp(argv[1], "sub") == 0) {
        if (argc != 4)
            printUsage(argv[0]);

        runSubscriber(argv[2], atoi(argv[3]));
    } else if (strcmp(argv[1], "rsp") == 0) {
        if (argc != 3)
            printUsage(argv[0]);

        runResponder(atoi(argv[2]));
    } else if (strcmp(argv[1], "req") == 0) {
        if (argc != 4)
            printUsage(argv[0]);

        runRequester(argv[2], atoi(argv[3]));
    }
#else
    runClient("127.0.0.1", 10010);
    // runServer(10086);
#endif
    return 0;
}
